/*
Copyright  2018 Blockchain Technology and Application Joint Lab, Fintech Research Center of ISCAS.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
 */
import settings from '../../setting.js';
import WebSocket from 'websocket';
import {Buffer} from 'buffer';
import root from '../repchainMessage';
import {Meteor} from 'meteor/meteor';
import {X509} from "jsrsasign";
import moment from 'moment';
import {RegisterUser} from "./register_user/register_user";
import {CopyrightCertificates} from './copyright_certificates/copyright_certificates';
import repchain from "./repchainUtil";

settings = new settings();
/**
 * 建立WebSocket连接，订阅出块信息并更新数据库
 */
exports.buildWS = function() {
    let event_message = root.rep.protos.Event;
    let server_url = 'ws://' + settings.websocket_host + ':' + settings.websocket_port + '/event';
    let socket = new WebSocket.w3cwebsocket(server_url);
    let timer;
    socket.binaryType = 'arraybuffer';
    socket.onerror = (err) => {
        console.log('Webscoket connect error: ', err);
    };
    socket.onopen = () => {
        console.log('Websocket connected');
        timer = setInterval(() => {
            socket.send('heartbeat')
        }, 5000);
    };
    socket.onclose = () => {
        console.log('Websocket connection closed');
    };
    socket.onmessage = Meteor.bindEnvironment((event) => {
        let data = new Uint8Array(event.data);
        let em = event_message.decode(data);
        if(em.action == 2){
            if(em.blk){
                let contains = false;
                let transactions = em.blk.transactions;
                transactions.forEach((item)=>{
                    if(item.payload.ctorMsg.hasOwnProperty('function') && item.type == 2){
                        let func_str = item.payload.ctorMsg.function.toString()
                        let func_args = item.payload.ctorMsg.args
                        if(func_str.search('^put_proof') == 0){// insert copyright certificate
                            let transaction = CopyrightCertificates.findOne({'certificate_number':item.txid})
                            if(transaction == undefined){
                                let reg_hash = /\".*?\"/g
                                let reg_res = func_args[0].match(reg_hash);
                                let digital_identity = reg_res[0].replace(/\"/g,'')
                                let des_base64 = reg_res[1].replace(/\"/g,'')
                                let des_buf = new Buffer(des_base64,'base64')
                                let des_info = JSON.parse(des_buf.toString('utf-8'))
                                des_info.certificate_number = item.txid;
                                des_info.block_timestamp = em.blk.timestamp.seconds.low;
                                des_info.status=true;
                                CopyrightCertificates.insert(des_info)
                            }else {
                                let certificate_update_info = {
                                    txid: item.txid,
                                    status: true,
                                    block_timestamp: em.blk.timestamp.seconds.low,
                                }
                                CopyrightCertificates.update({txid:item.txid},{$set:certificate_update_info})
                            }
                        }else if(func_str.search('^signup') == 0){//insert register users
                            let reg_hash = /\".*?\"/g
                            let reg_res = func_args[0].match(reg_hash);
                            let cert_base64 = reg_res[0].replace(/\"/g,'');
                            let info_base64 = reg_res[1].replace(/\"/g,'')
                            repchain.getAccountAddress(cert_base64, (err, res) => {
                                if(err){
                                    console.log(err)
                                    return;
                                }
                                let cert_pem = new Buffer(cert_base64, 'base64').toString();
                                let user_info = JSON.parse(new Buffer(info_base64,'base64').toString())
                                const cert = new X509();
                                cert.readCertPEM(cert_pem);
                                user_info['status']=true;
                                user_info['avatar']=faker.image.avatar();
                                user_info['user_certificate_pem']= cert_pem;
                                user_info['account_address'] = res;
                                user_info['createdAt'] = cert.getNotBefore();
                                RegisterUser.insert(user_info)
                            })

                        }else if(func_str.search('^destroyCert')==0){
                            console.log('delete user')
                            let reg_hash = /\".*?\"/g
                            let reg_res = func_args[0].match(reg_hash);
                            let addr = reg_res[0].replace(/\"/g,'')
                            Meteor.setTimeout(()=>{
                                let user = RegisterUser.findOne({'account_address':addr})
                                if(user != undefined){
                                    RegisterUser.update({account_address:addr},{$set:{status: false}})
                                }
                            },500)
                        }
                    }
                });
            }
        }
    });
}